﻿using CodingWheels.DataTypes.Core;

namespace CodingWheels.DataTypes
{
	public class DistanceUnit : Unit
	{
		public static readonly DistanceUnit Meters = new DistanceUnit("Meters", "m");
		public static readonly DistanceUnit Kilometers = new DistanceUnit("Kilometers", "km");
		public static readonly DistanceUnit Centimeters = new DistanceUnit("Centimeters", "cm");
		public static readonly DistanceUnit Millimeters = new DistanceUnit("Millimeters", "mm");
		public static readonly DistanceUnit Feet = new DistanceUnit("Feet", "ft");
		public static readonly DistanceUnit Inches = new DistanceUnit("Inches", "in");
		public static readonly DistanceUnit Miles = new DistanceUnit("Miles", "mi");
		public static readonly DistanceUnit NauticalMiles = new DistanceUnit("NauticalMiles", "nmi");
		public static readonly DistanceUnit Yards = new DistanceUnit("Yards", "yds");

		public DistanceUnit(string name, string symbol) : base(name, symbol)
		{
		}
	}

	public class Distance : DataType<Distance, DistanceUnit>
	{
		public Distance() : base(0, DistanceUnit.Meters)
		{
		}

		public Distance(double value, DistanceUnit unit) : base(value, unit)
		{
		}
	}

	internal class DistanceConverter : Converter<DistanceUnit>
	{
		public DistanceConverter()
		{
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Kilometers, DistanceUnit.Meters, 1000.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Meters, DistanceUnit.Feet, 3.2808399));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Meters, DistanceUnit.Inches, 39.3700787));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Miles, DistanceUnit.Meters, 1609.344));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.NauticalMiles, DistanceUnit.Meters, 1852.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Kilometers, DistanceUnit.Feet, 3280.8399));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Kilometers, DistanceUnit.Inches, 39370.0787));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Miles, DistanceUnit.Kilometers, 1.609344));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.NauticalMiles, DistanceUnit.Kilometers, 1.85200));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Feet, DistanceUnit.Inches, 12.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Miles, DistanceUnit.Feet, 5280));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.NauticalMiles, DistanceUnit.Feet, 6076.11549));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Miles, DistanceUnit.Inches, 63360.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.NauticalMiles, DistanceUnit.Inches, 72913.3858));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.NauticalMiles, DistanceUnit.Miles, 1.15077945));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Centimeters, DistanceUnit.Millimeters, 10.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Inches, DistanceUnit.Millimeters, 25.4));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Feet, DistanceUnit.Millimeters, 304.8));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Yards, DistanceUnit.Millimeters, 914.4));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Meters, DistanceUnit.Millimeters, 1000.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Kilometers, DistanceUnit.Millimeters, 1000000.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Miles, DistanceUnit.Millimeters, 1609344.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.NauticalMiles, DistanceUnit.Millimeters, 1852000.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Inches, DistanceUnit.Centimeters, 2.54));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Feet, DistanceUnit.Centimeters, 30.48));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Yards, DistanceUnit.Centimeters, 91.44));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Meters, DistanceUnit.Centimeters, 100.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Kilometers, DistanceUnit.Centimeters, 100000.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Miles, DistanceUnit.Centimeters, 160934.4));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.NauticalMiles, DistanceUnit.Centimeters, 185200.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Yards, DistanceUnit.Inches, 36.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Yards, DistanceUnit.Feet, 3.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Meters, DistanceUnit.Yards, 1.0936133));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Kilometers, DistanceUnit.Yards, 1093.6133));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.Miles, DistanceUnit.Yards, 1760.0));
			AddConversion(Conversion<DistanceUnit>.ConvertUsingMultiplication(DistanceUnit.NauticalMiles, DistanceUnit.Yards, 2025.37183));

		}
	}
}
